[...slug].astro

 1---
 2import { getCollection, render } from 'astro:content';
 3import Base from '../../layouts/Base.astro';
 4import '../../styles/sub-pages.css';
 5
 6export async function getStaticPaths() {
 7  const entries = await getCollection('tutorials');
 8  return entries.map(entry => ({
 9    params: { slug: entry.id },
10    props: { entry },
11  }));
12}
13
14const { entry } = Astro.props;
15const { Content } = await render(entry);
16---
17
18<Base
19  title={`${entry.data.title} | Impeccable`}
20  description={entry.data.description}
21  activeNav="docs"
22  canonicalPath={`/tutorials/${entry.id}`}
23  bodyClass="sub-page"
24>
25  <div class="tutorial-page">
26    <nav class="skills-breadcrumb" aria-label="Breadcrumb">
27      <a href="/docs">Docs</a>
28      <span aria-hidden="true">/</span>
29      <a href="/tutorials">Tutorials</a>
30      <span aria-hidden="true">/</span>
31      <span>{entry.data.title}</span>
32    </nav>
33
34    <header class="sub-page-header">
35      <span class="sub-page-eyebrow">Tutorial</span>
36      <h1 class="sub-page-title">{entry.data.title}</h1>
37      {entry.data.tagline && <p class="sub-page-lede">{entry.data.tagline}</p>}
38    </header>
39
40    <div class="skills-detail-body docs-body tutorial-body prose">
41      <Content />
42    </div>
43  </div>
44
45  <style>
46    .tutorial-page { max-width: 720px; margin: 0 auto; padding: 2rem 1.5rem 4rem; }
47    .tutorial-body { margin-top: 2rem; }
48  </style>
49</Base>